import json
import datetime
from common.heartbeat import ICMP, TCP
from common.metric import Metric
from package.connector.kafka_db import kafka_producer
from package.encode import CustomJson


metric_map = {item.MetricName: item for item in Metric.__subclasses__()}


class DevopsJob:
    HeartBeatTopic = 'devops_heartbeat'
    MetricTopicPrefix = 'devops_metric_'

    def heartbeat(self, devops):
        message = {'devops_id': devops.id, 'devops_name': devops.name, 'category': devops.category,
                   '_time': int(datetime.datetime.utcnow().timestamp() * 1000)}

        cls = TCP if devops.port else ICMP
        resp = cls(host=devops.host, port=devops.port).heartbeat()
        kafka_producer.send(self.HeartBeatTopic, value=json.dumps({**message, **resp, 'type': cls.__name__},
                                                                  ensure_ascii=False))

    def metric(self, devops):
        topic = f'{self.MetricTopicPrefix}{devops.category.lower()}'
        message = {'devops_id': devops.id, 'devops_name': devops.name, 'category': devops.category,
                   '_time': int(datetime.datetime.utcnow().timestamp() * 1000)}

        metric_cls = metric_map.get(devops.category)
        if not metric_cls:  # 其他监控暂不支持
            return

        try:
            instance = metric_cls()
            instance.init(**devops.configure, host=devops.ip, port=devops.port)
            metric = instance.metric()
            meta = {'code': 0, 'error': ''}
        except Exception as e:
            metric = {}
            meta = {'code': -1, 'error': str(e)}
        kafka_producer.send(topic, value=json.dumps({**message, **metric, **meta}, ensure_ascii=False, cls=CustomJson))


devops_job = DevopsJob()
